package com.common.print;

import java.util.concurrent.Semaphore;

/**
 * @ClassName Semaphore
 * @Description TODO
 * @Author admin
 * @Date 2021/4/28 16:34
 * @Version 1.0
 **/
public class SemaphoreDemo {

    /**
     * @Description: 信号量(Semaphore):在多线程环境下负责协调哥哥线程 以保证他们能够正确的 合理的使用公共资源。
     * Semaphore同步机制：当调用acquire()时，内部计数器减一；调用release()内部计数器加一。计数器不饿能小于0 如果等于0，acquire()会被阻塞，需要等待其他线程调用release()
     * @Author: liuhuanjin
     * @Date: 2021/4/28 16:42
     **/
    public static void main(String[] args) {
        Semaphore semaphoreA = new Semaphore(1);
        Semaphore semaphoreB = new Semaphore(0);
        Semaphore semaphoreC = new Semaphore(0);

        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    try {
                        semaphoreA.acquire();
                        System.out.println("A");
                    }catch (Exception e){
                        e.printStackTrace();
                    }finally {
                        semaphoreB.release();
                    }
                }
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    try {
                        semaphoreB.acquire();
                        System.out.println("B");
                    }catch (Exception e){
                        e.printStackTrace();
                    }finally {
                        semaphoreC.release();
                    }
                }
            }
        });

        Thread threadC = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    try {
                        semaphoreC.acquire();
                        System.out.println("C");
                    }catch (Exception e){
                        e.printStackTrace();
                    }finally {
                        semaphoreA.release();
                    }
                }
            }
        });

        threadA.start();
        threadB.start();
        threadC.start();
    }

}
